package com.mall.group_booking.service.impl;

import com.mall.constant.enums.BookingRootStatus;
import com.mall.constant.strings.ConstantStrings;
import com.mall.constant.strings.MapMsg;
import com.mall.entity.groupbooking.GbRecord;
import com.mall.entity.groupbooking.GbRoot;
import com.mall.group_booking.entity.GbItemVo;
import com.mall.group_booking.entity.GbRecordVo;
import com.mall.group_booking.mapper.BookingRecordMapper;
import com.mall.group_booking.service.BookingRecordService;
import com.mall.group_booking.service.BookingRootService;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author White
 */
@Service
public class BookingRecordServiceImpl implements BookingRecordService {

    @Autowired
    private BookingRecordMapper bookingRecordMapper;

    @Autowired
    private Redisson redisson;

    @Autowired
    private BookingRootService bookingRootService;

    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;

    /**
     * 查询指定用户下正在拼团的记录
     * @param rootId
     * @return
     */
    @Override
    public List<GbRecord> findRecordByRootId(Integer rootId) {
        return bookingRecordMapper.findRecordByRootId(rootId);
    }

    /**
     * 拼单记录添加到数据库
     * @param recordId 拼单记录id
     */
    @Override
    public void recordToMysql(Long recordId) {
        //获取redis中拼单记录map
        RMap<Long, GbRecordVo> recordMap = redisson.getMap(MapMsg.BOOKING_RECORD_REDIS_MAP);
        //获取当前对应的记录
        GbRecordVo gbRecordVo = recordMap.get(recordId);
        //将完成的拼单记录从redis中删除
        recordMap.remove(gbRecordVo.getId());
        //将记录添加到数据库中
        bookingRecordMapper.insert(gbRecordVo);
        //获取团map和拼团商品map
        RMap<Integer, GbRoot> rootMap = redisson.getMap(MapMsg.BOOKING_ROOT_REDIS_MAP);
        RMap<Long, GbItemVo> itemMap = redisson.getMap(MapMsg.BOOKING_ITEM_REDIS_MAP);
        //获取团
        GbRoot gbRoot =rootMap.get(gbRecordVo.getRootId());
        //根据商品id上锁，同时一个商品只有一个操作
        RLock lock = redisson.getLock(gbRoot.getSpecItemId().toString());
        try{
            lock.lock(5, TimeUnit.SECONDS);
            //获取商品
            GbItemVo gbItemVo = itemMap.get(gbRoot.getSpecItemId());
            //如果参与人数等于拼团成功人数
            if (gbRoot.getJoinCount().equals(gbItemVo.getCountPerson())){
                //删除团过期时间监听标志
                redisTemplate.delete(ConstantStrings.IF_BOOKING_ROOT_ID+gbRoot.getId());
                //修改团状态
                gbRoot.setStatus(BookingRootStatus.completed.getCode());
                //删除redis中成功的团
                rootMap.remove(gbRoot.getId());
                //更新到数据库
                bookingRootService.updateBookingRoot(gbRoot);
                //成团数量+1
                gbItemVo.setSuccessCount(gbItemVo.getSuccessCount()+1);
                //更新到redis中
                itemMap.put(gbItemVo.getSpecItemId(),gbItemVo);
            }
        }finally {
            lock.unlock();
        }
    }
}
